import io
import os
from flask import Flask, request, abort, send_file
from datetime import datetime
import json

from fileOP.fileOP import FileOP
from fileOP.fileIO import FileIO
from fileOP.filePack import FilePack

app = Flask(__name__)
with open("configs/test.json", "r") as f:
    config = json.load(f)
sensors = config["sensor"]


@app.get("/sensor")
def Sensor():
    sensorNames = ""
    for sensor in sensors:
        sensorNames += sensor["name"] + ","
    return sensorNames[:-1]


@app.get("/test")
def Test():
    return "This is a test!"


@app.get("/info")
def Info():
    port = request.environ.get("SERVER_PORT", "-1")

    return (
        "Current server is running on port "
        + str(port)
        + " with description: "
        + config["description"]
    )


@app.get("/data")
def Data():
    startTimeStr = request.args.get("startTime")  # startTime=2022_01_01_00_00
    endTimeStr = request.args.get("endTime")  # endTime=2022_01_01_00_00
    type = request.args.get("type")  # type=raw or post
    tag = request.args.get("tag")  # tag=sensor1

    if startTimeStr is None or endTimeStr is None:
        abort(400, description="startTime and endTime are required")
    try:
        startTime = datetime.strptime(startTimeStr, "%Y_%m_%d_%H_%M")
        endTime = datetime.strptime(endTimeStr, "%Y_%m_%d_%H_%M")
    except ValueError:
        abort(
            400,
            description="startTime and endTime should be in format 'YYYY_MM_DD_HH_MM'",
        )
    if startTime > endTime:
        abort(400, description="startTime should be earlier than endTime")
    if type is None:
        type = "csv"
    elif type not in ["raw", "post"]:
        abort(400, description="type should be 'raw' or 'post'")

    if not os.path.exists(os.path.join(config["dataDir"], tag)):
        abort(404, description="No data found for the given tag")
    tagop = FileOP(os.path.join(config["dataDir"], tag))
    files = tagop.GlobFilePathInRange(startTime, endTime, type, ".csv")
    if files == []:
        abort(404, description="No data found in the given time range")
    fileBytes = [FileIO(filePath).ReadByte() for filePath in files]
    data = FilePack.Pack(fileBytes)
    binaryFile = io.BytesIO(data)
    binaryFile.seek(0)
    return send_file(binaryFile, as_attachment=True, download_name="data.bin")


if __name__ == "__main__":
    app.run(debug=True)
